#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>

/* 处理SIGINT,CTRL+C*/
static void signal_handler_INT(int signo){
    printf("信号%d触发了。\n", signo);
    exit(0);
    return;
}

// 最基本的使用，处理SIGINT消息，收到SIGINT时候做一些资源释放等退出前的工作。
// 程序在前台使用CTRL+C触发，在后台使用"kill -2 PID"触发。
void test_sign_int(){
    printf("Paused to wait a signal (SIGINT=%d).\n", SIGINT);
    signal(SIGINT, signal_handler_INT);
    pause(); //暂停等待信号。
}

static void signal_handler(int signo){
    if (signo == SIGINT){
        printf("捕捉到SIGINT信号。\n");
    }else if (signo == SIGTERM){
        printf("捕捉到SIGTERM信号。\n");
    }else{
        printf("捕捉到信号%d。\n", signo);
    }
    exit(0);
}

// 各信号的值：SIGINT=2,SIGTERM=15,SIGPROF=27,SIGHUP=1
// 测试输入"bin/ch10signal &"让它在后台执行。
// 然后输入kill -signal_id pid向这个进程发送信号。
// "kill -2 pid" : 输出“捕捉到SIGINT信号”然后退出程序。
// "kill -15 pid" : 输出“捕捉到SIGTERM信号”然后退出程序。
// "kill -27 pid" : 无任何响应然后退出
// "kill -1 pid" ： 无任何响应，也不退出。
void test_set_default_and_ignore(){
    printf("SIGINT=%d,SIGTERM=%d,SIGPROF=%d,SIGHUP=%d\n", SIGINT, SIGTERM, SIGPROF, SIGHUP);
    // 让signal_handler处理SIGINT和SIGTERM信号。
    signal(SIGINT, signal_handler);   
    signal(SIGTERM, signal_handler);
    // 让程序按照默认方法处理SIGPROF信号。
    signal(SIGPROF, SIG_DFL);
    // 让程序忽略SIGHUP信号。
    signal(SIGHUP, SIG_IGN);
    while (1)
    {
        pause();
        printf("Program still running.\n");
    }
}

//信号集
//"bin/ch10signal &"
//"kill -2 pid" 无任何响应，程序继续运行
//"kill -15 pid" 无任何响应，程序继续运行
//"kill -1 pid" "[1]+  挂起                  bin/ch10signal"
static void signal_handler_sets(int signo){
    if (signo == SIGINT){
        printf("不会响应SIGINT信号。\n");
    }else if (signo == SIGTERM){
        printf("不会响应SIGTERM信号。\n");
    }else{
        printf("捕捉到信号%d。\n", signo);
    }
    exit(0);
}
void test_signal_set(){
    sigset_t sig_set;
    sigemptyset(&sig_set);
    sigaddset(&sig_set, SIGINT);
    sigaddset(&sig_set, SIGTERM);
    sigprocmask(SIG_BLOCK, &sig_set, NULL);
    signal(SIGINT, signal_handler_sets);
    signal(SIGTERM, signal_handler_sets);
    while (1){
        pause();
    }
}

int main(int argc, char** argv)
{
    printf("Test using of signal.\n");
    //test_sign_int();
    //test_set_default_and_ignore();
    test_signal_set();
    return 0;
}
